// #include <stdio.h>
// #include <stdlib.h>
// #include <unistd.h>
// #include <sys/types.h>
// #include <sys/wait.h>
// #include <errno.h>


// void RunChild()
// {
//     int cnt = 2;
//     while(cnt)
//     {
//         printf("i am child process, pid: %d, ppid: %d, cnt: %d\n", getpid(), getppid(), cnt);
//         cnt--;
//         sleep(1);
//     }
// }

// int main()
// {
//     //创建5个子进程 并让子进程保留2s
//     pid_t id = 0;
//     for(int i = 0; i < 5; i++)
//     {
//         id = fork();
//         //分离父子进程，子进程退出
//         if(id == 0)
//         {
//             RunChild();
//             exit(i);//子进程i作为退出码
//         }
//     }
    
//     if(id < 0)
//     {
//         perror("fork");
//         return 1;
//     }
//     else if(id == 0)
//     {
//         RunChild();
//         exit(0);
//     }
//     else 
//     {
//         //id > 0
//         sleep(4);
//         int status = 0;
//         for(int i = 0; i < 5; i++)
//         {
//             pid_t ret = waitpid(-1, &status, 0);
//             if(WIFEXITED(status))//退出信号非0 正常退出
//             {
//                 printf("我是父进程，我等待子进程成功了, 子进程的pid: %d , 我的退出码是 %d\n", ret, WIFEXITED(status));//子进程真实退出码为waitpid的返回值
//             }
//             else 
//             {
//                 printf("退出异常\n");
//             }
//         }
//     }

//     return 0;
// }

/*
func:让父进程在非阻塞轮询期间做自己的
定义函数指针类型 利用函数指针进行回调 

*/


#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>

#define NUM 3
//定义函数指针类型
typedef void (*func_t)();
//定义函数指针数组
func_t handlers[NUM+1];
//顶义业务函数
void Down_Load(){
  printf("下载中\n");
}

void Flush(){
  printf("下载完，更新中\n");
}

void Load(){
  printf("更新完，加载中\n");
}

void RunChild()
{
    sleep(4);
    exit(1);
}

//定义注册表
void Register(func_t arr[], func_t func){
    for(int i = 0; i<NUM; i++){
      arr[i] = func;
      arr[i]();
      arr[i+1] = NULL;
    }
}

int main()
{
    pid_t id = fork();
    if(id < 0)
    {
        perror("fork");
        return 1;
    }

    else if(id == 0)
    {
        RunChild();
        //exit(0);
    }

    else 
    {
        //id > 0
            sleep(2);
            while(1){
            int status = 0;      
            pid_t ret = waitpid(-1, &status, WNOHANG);
            if(ret > 0)//正常退出
            {
                printf("我是父进程，我等待子进程成功了, 子进程的pid: %d , 我的退出码是 %d\n", ret, WIFEXITED(status));//子进程真实退出码为WEXITSTATUS(status)
                break;
            }

            else if(ret == 0)//阻塞轮询 父进程将对应函数写入注册表
            {
              Register(handlers, Down_Load);
              sleep(1);
              Register(handlers, Flush);
              sleep(1);
              Register(handlers, Load);
            }

            else{//异常退出
              // if(WIFSIGNALED(status) == 1)
              // printf("退出信号为:%d ",WTERMSIG(status));
            }

        }
            
    }

    return 0;
}




// #include <stdio.h>
// #include <stdlib.h>
// #include <unistd.h>
// #include <sys/types.h>
// #include <sys/wait.h>
// #include <errno.h>

// #define NUM 3

// // 定义函数指针类型
// typedef void (*func_t)();

// // 定义业务函数
// void Down_Load() { printf("下载中\n"); }
// void Flush() { printf("下载完，更新中\n"); }
// void Load() { printf("更新完，加载中\n"); }

// // 定义函数指针数组并初始化
// func_t handlers[NUM] = {Down_Load, Flush, Load};

// void RunChild() {
//     sleep(4);  // 子进程运行4秒后退出
//     exit(1);   // 退出码为1
// }

// int main() {
//     pid_t id = fork();
//     if (id < 0) {
//         perror("fork");
//         return 1;
//     } else if (id == 0) {
//         RunChild();  // 子进程
//     } else {
//         // 父进程
//         int status;
//         int current_handler = 0;  // 当前要执行的handler索引
        
//         while (1) {
//             pid_t ret = waitpid(id, &status, WNOHANG);
            
//             if (ret > 0) {
//                 // 子进程已退出
//                 if (WIFEXITED(status)) {
//                     printf("子进程 %d 正常退出，退出码: %d\n", 
//                            ret, WEXITSTATUS(status));
//                 } else {
//                     printf("子进程异常退出\n");
//                 }
//                 break;  // 退出循环
//             } else if (ret == 0) {
//                 // 子进程仍在运行，执行当前handler
//                 if (current_handler < NUM) {
//                     handlers[current_handler]();  // 调用当前handler
//                     current_handler++;
//                 }
//                 sleep(1);  // 避免CPU占用过高
//             } else {
//                 // waitpid出错
//                 perror("waitpid");
//                 //printf("%d",  WTERMSIG(status));
//                 break;
//             }
//         }
//     }
//     return 0;
// }